/**
 *    @file       epoll.h
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       02/12/2014 06:30:47 PM
 *
 *    @author     Theophilus (), wangtf418@gmail.com
 */
#ifndef _BF_EPOLL_H_
#define _BF_EPOLL_H_
#include <sys/epoll.h>
#include "comdef.h"

typedef struct epoll_event bf_epoll_event_t;
enum bf_epoll_event_value_t
{
	BF_EPOLL_IN = EPOLLIN,
	BF_EPOLL_OUT = EPOLLOUT,
	BF_EPOLL_ERR = EPOLLERR,
	BF_EPOLL_HUP = EPOLLHUP,
	BF_EPOLL_ET = EPOLLET
};

class epoll
{
public:
	epoll();
	~epoll();

public:
	inline bf_epoll_event_t * get_next_avail()
	{
		if (m_avail_index >= m_avail_num) return NULL;
		return m_events + (m_avail_index ++);
	}
	template<typename _Tcallback>
	bf_int_t process(_Tcallback &callback)
	{
		for (bf_int_t i = 0; i < m_avail_num; i ++)
		{
			callback.process_epoll_event(m_events[i]);
		}
		return BF_OK;
	}

public:
	bf_int_t init(bf_int_t epoll_size, bf_int_t wait_time);

public:
	bf_int_t add(bf_int_t sockfd, bf_int_t events, void *append_data);
	bf_int_t del(bf_int_t sockfd, void *append_data);
	bf_int_t modify(bf_int_t sockfd, bf_int_t events, void *append_data);
	bf_int_t wait();
	bf_int_t wait(bf_int_t wait_time);
private:
	bf_int_t m_fd;
	bf_int_t m_size;
	bf_int_t m_wait_time;
	bf_epoll_event_t *m_events;
	bf_int_t m_avail_num;
	bf_int_t m_avail_index;
};

#endif

